// System.cpp

#include <QSysInfo>
#include <QProcess>
#include <QDir>
#include <QFile>
#include <QRegularExpression>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QDebug>
#include <QSysInfo>
#include <QStorageInfo>
#include "system.h"
#include "db.h"
#include "global.h"
#include "u.h"

bool System::checkSerialNumber(const QString &serialNumber)
{
    QStringList parts = serialNumber.split("-");
    if (parts.size() < 2) return false;
    if (!U::validateDateStr(parts[0])) return false;

    QString hex = U::getMD5(U::reverseString(m_machineId+"*lepure@2025" + parts[0]));
    qDebug() << "hex:" << hex;
    if(hex.right(8).compare(parts[1]) != 0) return false;
    qDebug() << "compare serial number success" << hex;
    return true;
}

QString System::getDeadLine(const QString& number)
{
    QStringList parts = number.split("-");
    if (parts.size() < 2) return QString("");
    return U::getDateStrFromStr(parts[0]);
}

QString System::getSerialNumber()
{
    DB* db = DB::getInstance();
    qDebug() << "debug>>>>>>";
    return db->getParamValue("product_serialNumber");
}

bool System::saveParam(const QString &param, const QString &value, const QString& name)
{
    DB* db = DB::getInstance();
    qDebug() << "debug>>>>>>";
    db->saveParamValue(param, value, name);
    return true;
}

QString System::getParam(const QString &param)
{
    DB* db = DB::getInstance();
    qDebug() << "debug>>>>>>";
    return db->getParamValue(param);
}

bool System::saveSerialNumber(const QString& number, const QString& name)
{
    DB* db = DB::getInstance();
    qDebug() << "debug>>>>>>";
    db->saveParamValue("product_serialNumber", number, name);
    return true;
}

System::System(QObject *parent)
    : QObject(parent)
{
    updateOSInfo();
    updateCPUInfo();
    updateMemoryInfo();
    updateDiskInfo();
    updateNetworkInfo();
    m_machineId =  QSysInfo::machineUniqueId().toUpper();
    m_machineType = DB::getInstance()->getParamValue("machine_type");
    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this, &System::updateSystem);
    m_timer->start(2000); // 2秒刷新（
}

QString System::osName() const { return m_osName; }
QString System::cpuModel() const { return m_cpuModel; }
int System::cpuCoreCount() const { return m_cpuCoreCount; }
double System::cpuUsage() const { return m_cpuUsage; }
qint64 System::totalMemory() const { return m_totalMemory; }
qint64 System::freeMemory() const { return m_freeMemory; }
QString System::diskUsage() const { return m_diskUsage; }
QString System::networkInfo() const { return m_networkInfo; }
QString System::machineId() const { return m_machineId; }
QString System::softwareVersion() const { return QString("V1.0_%1").arg(U::getCompileDate());}
QString System::machineType() const{return m_machineType;}

void System::updateSystem()
{
    updateOSInfo();
    updateCPUInfo();
    updateMemoryInfo();
    updateDiskInfo();
    updateNetworkInfo();

    emit osNameChanged();
    emit cpuModelChanged();
    emit cpuCoreCountChanged();
    emit cpuUsageChanged();
    emit totalMemoryChanged();
    emit freeMemoryChanged();
    emit diskUsageChanged();
    emit networkInfoChanged();
}

void System::updateOSInfo()
{
    m_osName = QSysInfo::prettyProductName();
}

void System::updateCPUInfo()
{
    // // 获取 CPU 核心数
    // SYSTEM_INFO sysInfo;
    // GetSystem(&sysInfo);
    // m_cpuCoreCount = sysInfo.dwNumberOfProcessors;

    // // 从注册表读取 CPU 型号
    // HKEY hKey;
    // const wchar_t* regPath = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
    // if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, regPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
    //     char cpuModel[256] = {0};
    //     DWORD size = sizeof(cpuModel);
    //     DWORD type = REG_SZ;
    //     if (RegQueryValueExW(hKey, L"ProcessorNameString", nullptr, &type, (LPBYTE)cpuModel, &size) == ERROR_SUCCESS) {
    //         m_cpuModel = QString::fromUtf8(cpuModel);
    //     }
    //     RegCloseKey(hKey);
    // }

    // if (m_cpuModel.isEmpty()) {
    //     m_cpuModel = "未知 CPU 型号";
    // }

    // // 计算 CPU 使用率
    // FILETIME systemTime, idleTime, kernelTime, userTime;
    // if (GetSystemTimes(&systemTime, &idleTime, &kernelTime)) {
    //     ULONGLONG lastSystem = (ULONGLONG(m_lastSystemTime.dwHighDateTime) << 32) + m_lastSystemTime.dwLowDateTime;
    //     ULONGLONG lastIdle = (ULONGLONG(m_lastIdleTime.dwHighDateTime) << 32) + m_lastIdleTime.dwLowDateTime;
    //     ULONGLONG lastKernel = (ULONGLONG(m_lastKernelTime.dwHighDateTime) << 32) + m_lastKernelTime.dwLowDateTime;
    //     ULONGLONG lastUser = (ULONGLONG(m_lastUserTime.dwHighDateTime) << 32) + m_lastUserTime.dwLowDateTime;

    //     ULONGLONG currSystem = (ULONGLONG(systemTime.dwHighDateTime) << 32) + systemTime.dwLowDateTime;
    //     ULONGLONG currIdle = (ULONGLONG(idleTime.dwHighDateTime) << 32) + idleTime.dwLowDateTime;
    //     ULONGLONG currKernel = (ULONGLONG(kernelTime.dwHighDateTime) << 32) + kernelTime.dwLowDateTime;
    //     ULONGLONG currUser = (ULONGLONG(userTime.dwHighDateTime) << 32) + userTime.dwLowDateTime;

    //     ULONGLONG systemDelta = currSystem - lastSystem;
    //     ULONGLONG idleDelta = currIdle - lastIdle;

    //     if (m_firstSample) {
    //         m_firstSample = false;
    //         m_cpuUsage = 0.0;
    //     } else {
    //         if (systemDelta > 0) {
    //             double usage = 1.0 - (double)idleDelta / (double)systemDelta;
    //             m_cpuUsage = usage * 100.0; // 百分比
    //         } else {
    //             m_cpuUsage = 0.0;
    //         }
    //     }

    //     // 更新历史值
    //     m_lastSystemTime = systemTime;
    //     m_lastIdleTime = idleTime;
    //     m_lastKernelTime = kernelTime;
    //     m_lastUserTime = userTime;
    // } else {
    //     m_cpuUsage = 0.0; // 获取失败时保持上一次值
    // }
}

void System::updateMemoryInfo()
{
    // MEMORYSTATUSEX memInfo;
    // memInfo.dwLength = sizeof(MEMORYSTATUSEX);
    // if (GlobalMemoryStatusEx(&memInfo)) {
    //     m_totalMemory = memInfo.ullTotalPhys;
    //     m_freeMemory = memInfo.ullAvailPhys;
    // } else {
    //     m_totalMemory = 0;
    //     m_freeMemory = 0;
    // }
}

void System::updateDiskInfo()
{
    // ULARGE_INTEGER freeBytes, totalBytes, totalFree;
    // if (GetDiskFreeSpaceExW(L"C:", &freeBytes, &totalBytes, &totalFree)) {
    //     double usedPercent = (double)(totalBytes.QuadPart - freeBytes.QuadPart) / totalBytes.QuadPart * 100.0;
    //     qint64 usedGB = (totalBytes.QuadPart - freeBytes.QuadPart) / (1024 * 1024 * 1024);
    //     qint64 totalGB = totalBytes.QuadPart / (1024 * 1024 * 1024);
    //     m_diskUsage = QString("C: %1% (已用: %2 GB / 总计: %3 GB)")
    //                       .arg(qRound(usedPercent))
    //                       .arg(usedGB)
    //                       .arg(totalGB);
    // } else {
    //     m_diskUsage = "C盘信息获取失败";
    // }
    if (Global::instance().getStr("OS").compare("windows") == 0){
        QStorageInfo storage("C:");

        // 检查磁盘是否存在且可用
        if (storage.isValid() && storage.isReady()) {
            // 总容量（字节）
            qint64 totalSize = storage.bytesTotal();
            // 已使用容量（字节）
            qint64 usedSize = totalSize - storage.bytesFree();
            // 可用容量（字节）
            qint64 freeSize = storage.bytesFree();

            // 转换为 GB（1 GB = 1024^3 字节）
            double totalGB = totalSize / (1024.0 * 1024.0 * 1024.0);
            double usedGB = usedSize / (1024.0 * 1024.0 * 1024.0);
            double freeGB = freeSize / (1024.0 * 1024.0 * 1024.0);

            m_diskUsage = QString("C: %1% (可用: %2 GB/ 总计: %3 GB)")
                              .arg(qRound(usedGB/totalGB*100))
                              .arg(freeGB)
                              .arg(totalGB);
        } else {
            qDebug() << "无法访问 C 盘或磁盘不可用";
        }
    }

    if (Global::instance().getStr("OS").compare("ubuntu") == 0){
        QStorageInfo storage("/");

        // 检查磁盘是否存在且可用
        if (storage.isValid() && storage.isReady()) {
            // 总容量（字节）
            qint64 totalSize = storage.bytesTotal();
            // 已使用容量（字节）
            qint64 usedSize = totalSize - storage.bytesFree();
            // 可用容量（字节）
            qint64 freeSize = storage.bytesFree();

            // 转换为 GB（1 GB = 1024^3 字节）
            double totalGB = totalSize / (1024.0 * 1024.0 * 1024.0);
            double usedGB = usedSize / (1024.0 * 1024.0 * 1024.0);
            double freeGB = freeSize / (1024.0 * 1024.0 * 1024.0);

            m_diskUsage = QString("根目录/ 可用: %1 GB/ 总计: %2 GB")
                              .arg(freeGB)
                              .arg(totalGB);
        } else {
            qDebug() << "无法访问根目录/或磁盘不可用";
        }
    }

}

void System::updateNetworkInfo()
{
    QString info;
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    for (const QNetworkInterface &iface : interfaces) {
        if (iface.flags().testFlag(QNetworkInterface::IsUp) &&
            !iface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
            for (const QNetworkAddressEntry &entry : iface.addressEntries()) {
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                    info += QString("%1: %2\n")
                    .arg(iface.humanReadableName())
                        .arg(entry.ip().toString());
                }
            }
        }
    }
    m_networkInfo = info.isEmpty() ? "无活动网络接口" : info.trimmed();
}

void System::updateseq()
{

}
